package org.geekbang.time.mathbasicthought.lesson11_width_first_traversal;

import java.io.File;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 * 在计算机操作系统中，我们常常需要查看某个目录下的文件或子目录。
 * 现在给定一个目录的路径，请分别使用深度优先和广度优先遍历，列出该目录下所有的文件和子目录。
 * 对于子目录，需要进一步展示其下的文件和子目录，直到没有更多的子目录。
 */
public class ThinkTest {
    public static String targetDir = "C:\\Users\\T480\\Desktop\\dev-cache\\22 - 勘探院";

    public static void main(String[] args) {
        //dfs();
        System.out.println("------分割线--------");
        bfs();
    }

    public static void dfs() {
        File root = new File(targetDir);
        if (!root.isDirectory()) {
            System.out.println(root.getName());
            return;
        }

        Stack<File> stack = new Stack<>();
        stack.push(root);

        while (!stack.isEmpty()) {
            // 弹出第一个元素
            File file = stack.pop();
            System.out.println(file.getName());

            // 保证和外面的stack处理顺序一致
            Stack<File> tempStack = new Stack<>();

            if (file.isDirectory()) {
                File[] subFiles = file.listFiles();
                for (File subFile : subFiles) {
                    tempStack.push(subFile);
                }
            }

            while (!tempStack.isEmpty()) {
                stack.push(tempStack.pop());
            }
        }
    }

    public static void bfs() {
        File root = new File(targetDir);
        if (!root.isDirectory()) {
            System.out.println(root.getName());
            return;
        }

        Queue<File> queue = new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()) {
            File file = queue.poll();
            System.out.println(file.getName());

            if (file.isDirectory()) {
                File[] subFiles = file.listFiles();
                for (File subFile : subFiles) {
                    queue.offer(subFile);
                }
            }
        }
    }
}
